"""Support for LaMetric selects."""

from __future__ import annotations

from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from typing import Any

from demetriek import BrightnessMode, Device, LaMetricDevice

from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback

from .coordinator import LaMetricConfigEntry, LaMetricDataUpdateCoordinator
from .entity import LaMetricEntity
from .helpers import lametric_exception_handler


@dataclass(frozen=True, kw_only=True)
class LaMetricSelectEntityDescription(SelectEntityDescription):
    """Class describing LaMetric select entities."""

    current_fn: Callable[[Device], str]
    select_fn: Callable[[LaMetricDevice, str], Awaitable[Any]]


SELECTS = [
    LaMetricSelectEntityDescription(
        key="brightness_mode",
        translation_key="brightness_mode",
        entity_category=EntityCategory.CONFIG,
        options=["auto", "manual"],
        current_fn=lambda device: device.display.brightness_mode.value,
        select_fn=lambda api, opt: api.display(brightness_mode=BrightnessMode(opt)),
    ),
]


async def async_setup_entry(
    hass: HomeAssistant,
    entry: LaMetricConfigEntry,
    async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
    """Set up LaMetric select based on a config entry."""
    coordinator = entry.runtime_data
    async_add_entities(
        LaMetricSelectEntity(
            coordinator=coordinator,
            description=description,
        )
        for description in SELECTS
    )


class LaMetricSelectEntity(LaMetricEntity, SelectEntity):
    """Representation of a LaMetric select."""

    entity_description: LaMetricSelectEntityDescription

    def __init__(
        self,
        coordinator: LaMetricDataUpdateCoordinator,
        description: LaMetricSelectEntityDescription,
    ) -> None:
        """Initiate LaMetric Select."""
        super().__init__(coordinator)
        self.entity_description = description
        self._attr_unique_id = f"{coordinator.data.serial_number}-{description.key}"

    @property
    def current_option(self) -> str | None:
        """Return the selected entity option to represent the entity state."""
        return self.entity_description.current_fn(self.coordinator.data)

    @lametric_exception_handler
    async def async_select_option(self, option: str) -> None:
        """Change the selected option."""
        await self.entity_description.select_fn(self.coordinator.lametric, option)
        await self.coordinator.async_request_refresh()
